#coding=utf-8
#提供簡單的檔案鎖功能

import os

#class lockException(Exception): pass
class acquireException(Exception): pass #當重複鎖定時拋出
class initException(Exception): pass #如果init失敗拋出本意外

class FileLock:
    '''簡單的檔案鎖功能
    用來檢查指定位置的鎖存在或否
    '''

    def __init__(self, lockFile = ''):
        '''執行初始化，在初始化階段就要指定檔案鎖是哪一個，日後不得更改'''
        #檢查檔名不能為空字串
        if lockFile == '':
            raise initException('Filelock\'s file name is empty.')

        #組合檔名與路徑，並紀錄下來
        self.lockFile = lockFile
        self.isLock = False

    def acquire(self):
        '''嘗試獲取指定檔案鎖，失敗拋出Exception意外'''
        #如果當前檔案鎖早已鎖住還要再鎖一次(這可不是正常用法)，則拋出異常
        if self.isLock:
            raise acquireException('This object can not lock again，you need release() first.')

        #嘗試實際獲取檔案鎖
        if os.path.isfile(self.lockFile) or not os.path.isdir(os.path.dirname(self.lockFile)): #如果檔案鎖原本就存在當然獲取失敗……
            raise acquireException('Filelock acuqire fail!')
        else: #如果檔案鎖原本不存在，則建立檔案並表示獲取成功
            with open(self.lockFile, mode = 'w', encoding = 'utf-8') as File:
                File.write('this is a filelock.')
            #更新內部資料
            self.isLock = True

    def release(self):
        '''如果檔案鎖處於已鎖狀態，釋放檔案鎖
        '''
        if self.isLock:
            if os.path.isfile(self.lockFile): #先檢查確定目標鎖存在沒給人亂動刪掉，這才實際進行刪除
                os.remove(self.lockFile)
            self.isLock = False

    def __enter__(self):
        '''進入with區段時的行為
        '''
        self.acquire()

    def __exit__(self):
        '''離開with區段時的行為
        '''
        self.release()

    def __del__(self):
        '''釋放物件時的行為'''
        self.release()
